package com.zust.data.serivce;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.zust.data.dal.UserRepository;
import com.zust.data.domain.param.*;
import com.zust.data.domain.vo.UserBackVo;
import com.zust.data.dto.ResponseDto;
import com.zust.data.dto.SessionInfo;
import com.zust.data.entity.DlUser;
import com.zust.data.entity.QDlUser;
import com.zust.data.util.MD5Util;
import com.zust.data.util.RegexUtil;
import com.zust.data.util.StrUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.inject.Inject;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author senselyan
 * @Description: 用户服务类
 * @date 2018/4/4 16:24
 */
@Service
public class UserService {

    @Inject
    private UserRepository userRepository;


    public ResponseDto doRegister(UserRegParam userRegParam) throws InvocationTargetException, IllegalAccessException, UnsupportedEncodingException, NoSuchAlgorithmException {
        if (StrUtil.hasEmpty(userRegParam.getPwd(), userRegParam.getEmail(), userRegParam.getUname())) {
            return new ResponseDto(false, "信息不完整");
        } else if (!RegexUtil.emailPattern.matcher(userRegParam.getEmail()).find()) {
            return new ResponseDto(false, "邮箱格式错误");
        } else if (!ObjectUtils.isEmpty(userRepository.findByEmailAndDeletedFlag(userRegParam.getEmail(), 0))) {
            return new ResponseDto(false, "邮箱已注册");
        } else {
            DlUser dlUser = new DlUser();
            BeanUtils.copyProperties(userRegParam, dlUser);
            dlUser.setPwd(MD5Util.getEncryptedPwd(userRegParam.getPwd()));
            return new ResponseDto(true, "注册成功", userRepository.save(dlUser));
        }
    }

    public ResponseDto doLogin(UserLoginParam userLoginParam, HttpSession session) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvocationTargetException, IllegalAccessException {
        if (StrUtil.hasEmpty(userLoginParam.getPwd(), userLoginParam.getEmail())) {
            return new ResponseDto(false, "请填写完整");
        } else if (0 == userRepository.countAllByEmailAndDeletedFlag(userLoginParam.getEmail(), 0)) {
            return new ResponseDto(false, "账户不存在");
        } else {
            DlUser dlUser = userRepository.findByEmailAndDeletedFlag(userLoginParam.getEmail(), 0);
            if (userLoginParam.getPwd().equals(dlUser.getPwd()) || MD5Util.validPassword(userLoginParam.getPwd(), dlUser.getPwd())) {
                SessionInfo sessionInfo = new SessionInfo();
                BeanUtils.copyProperties(dlUser, sessionInfo);
                session.setAttribute("sessionInfo", sessionInfo);
                session.setAttribute(StrUtil.session_val_menu_type, 0);


                return new ResponseDto(true, "登陆成功", sessionInfo);
            } else {
                return new ResponseDto(false, "密码错误");
            }
        }
    }

    public ResponseDto doSetBase(String userId, UserSetBaseParam userSetBaseParam) {
        if (ObjectUtils.isEmpty(userSetBaseParam) || StringUtils.isEmpty(userId)) {
            return new ResponseDto(false, "修改失败，缺少重要信息，请刷新页面");
        } else {
            DlUser dlUser = userRepository.findOne(userId);
            BeanUtils.copyProperties(userSetBaseParam, dlUser);
            userRepository.save(dlUser);
            return new ResponseDto(true, "操作成功");
        }
    }
    public ResponseDto doSetIcon(String userId, String icon) {
        if (ObjectUtils.isEmpty(icon) || StringUtils.isEmpty(userId)) {
            return new ResponseDto(false, "修改失败，缺少重要信息，请刷新页面");
        } else {
            DlUser dlUser = userRepository.findOne(userId);
            dlUser.setIcon(icon);
            userRepository.save(dlUser);
            return new ResponseDto(true, "操作成功");
        }
    }
    public ResponseDto doSetPwd(String userId, UserSetPwdParam userSetPwdParam) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        if (ObjectUtils.isEmpty(userSetPwdParam) || StringUtils.isEmpty(userId)) {
            return new ResponseDto(false, "修改失败，缺少重要信息，请刷新页面");
        } else {
            DlUser dlUser = userRepository.findOne(userId);
            if (userSetPwdParam.getOldPwd().equals(dlUser.getPwd()) || MD5Util.validPassword(userSetPwdParam.getOldPwd(), dlUser.getPwd())) {
                dlUser.setPwd(MD5Util.getEncryptedPwd(userSetPwdParam.getPwd()));
                userRepository.save(dlUser);
                return new ResponseDto(true, "操作成功");
            } else {
                return new ResponseDto(false, "原始密码错误");
            }
        }
    }

    public ResponseDto getUserInfo(String userId) {
        DlUser dlUser = userRepository.findOne(userId);
        if (ObjectUtils.isEmpty(dlUser)) {
            return new ResponseDto(false, "该用户不存在");
        } else {
            UserBackVo userBackVo = new UserBackVo();
            BeanUtils.copyProperties(dlUser, userBackVo);
            return new ResponseDto(true, "获取成功", userBackVo);
        }
    }




    public Page<DlUser> list(Pageable pageable, UserListParam userListParam) {
        Optional<BooleanExpression> booleanExp = getSearchQueryFromSearchDTO(userListParam);
        Page<DlUser> page;
//        if (booleanExp.isPresent())
//            page = userRepository.findAll(booleanExp.get(), pageable);
//        else
        page = userRepository.findAllByDeletedFlag(0, pageable);
        return page;
    }

    public DlUser save(DlUser dlUser) {
        dlUser.setDeletedFlag(0);
        dlUser = userRepository.insert(dlUser);
        return dlUser;
    }


    private Optional<BooleanExpression> getSearchQueryFromSearchDTO(UserListParam userListParam) {

        List<BooleanExpression> booleanExps = new ArrayList<>();
        QDlUser qDlUser = new QDlUser("dlUser");


        if (StringUtils.isNotBlank(userListParam.getName())) {
            booleanExps.add(qDlUser.name.eq(userListParam.getName()));
        }
        if (!ObjectUtils.isEmpty(userListParam.getType())) {
            booleanExps.add(qDlUser.type.eq(userListParam.getType()));
        }
        if (!ObjectUtils.isEmpty(userListParam.getStatus())) {
            booleanExps.add(qDlUser.status.eq(userListParam.getStatus()));
        }
        return booleanExps.stream().reduce((acc, element) -> acc.and(element));

    }
}
